#pragma once

#include <cstdint>
#include <cstddef>
#include <cmath>

namespace esphome::cc1101 {

// CC1101 Design Note DN013

struct PowerTableItem {
  uint8_t value;
  uint8_t dbm_diff;  // starts from 12.0, diff to previous entry, scaled by 10

  static uint8_t find(const PowerTableItem *items, size_t count, float &dbm_target) {
    int32_t dbmi = 120;
    int32_t dbmi_target = static_cast<int32_t>(std::lround(dbm_target * 10));
    for (size_t i = 0; i < count; i++) {
      dbmi -= items[i].dbm_diff;
      if (dbmi_target >= dbmi) {
        // Skip invalid PA settings (magic numbers derived from TI DN013/SmartRC logic)
        if (items[i].value >= 0x61 && items[i].value <= 0x6F) {
          continue;
        }
        dbm_target = static_cast<float>(dbmi) / 10.0f;
        return items[i].value;
      }
    }
    dbm_target = -30.0f;
    return 0x03;
  }
};

static const PowerTableItem PA_TABLE_315[] = {
    {0xC0, 14},  // C0 10.6 -35.3 -44.4 -57.8 -53.8 -58.3 -57.2 -57.8 -56.7 28.5
    {0xC3, 10},  // C3 9.6 -39.2 -45.3 -59.0 -54.2 -59.0 -57.5 -58.3 -57.2 26.2
    {0xC6, 11},  // C6 8.5 -43.2 -46.3 -59.2 -54.7 -59.1 -57.7 -58.3 -57.4 24.4
    {0xC9, 10},  // C9 7.5 -47.0 -47.3 -58.9 -55.0 -59.0 -57.9 -58.4 -57.5 23.0
    {0x81, 12},  // 81 6.3 -49.2 -45.7 -57.3 -53.6 -59.0 -56.0 -56.5 -57.5 19.5
    {0x85, 13},  // 85 5.0 -51.0 -47.2 -59.8 -54.2 -59.0 -56.9 -57.9 -58.0 18.3
    {0x88, 11},  // 88 3.9 -46.6 -48.1 -60.0 -55.0 -58.9 -57.5 -58.2 -58.2 17.4
    {0xCF, 11},  // CF 2.8 -49.8 -51.3 -57.6 -56.8 -59.1 -58.4 -58.1 -58.3 18.0
    {0x8D, 11},  // 8D 1.7 -43.8 -49.5 -58.9 -56.3 -58.8 -58.2 -58.4 -58.5 15.8
    {0x50, 10},  // 50 0.7 -59.2 -51.2 -59.0 -56.5 -59.0 -58.3 -58.3 -58.2 15.3
    {0x40, 10},  // 40 -0.3 -58.2 -52.1 -59.4 -56.9 -59.0 -58.4 -58.4 -58.3 14.7
    {0x3D, 10},  // 3D -1.3 -54.4 -48.4 -59.8 -57.5 -58.9 -58.3 -58.5 -58.5 19.3
    {0x55, 10},  // 55 -2.3 -56.7 -53.6 -59.7 -57.5 -59.1 -58.7 -58.4 -58.4 13.7
    {0x39, 11},  // 39 -3.4 -50.9 -49.5 -59.8 -58.0 -59.0 -58.5 -58.4 -58.4 16.8
    {0x2B, 15},  // 2B -4.9 -51.2 -50.4 -59.9 -58.0 -58.9 -58.7 -58.3 -58.4 15.6
    {0x29, 16},  // 29 -6.5 -51.8 -51.6 -59.9 -58.4 -59.0 -58.8 -58.3 -58.3 14.7
    {0x28, 10},  // 28 -7.5 -52.2 -52.5 -60.0 -58.6 -59.0 -58.8 -58.2 -58.4 14.3
    {0x27, 11},  // 27 -8.6 -52.9 -53.1 -60.0 -58.8 -59.1 -58.8 -58.3 -58.5 13.9
    {0x26, 12},  // 26 -9.8 -53.6 -54.3 -60.1 -58.7 -59.0 -58.7 -58.4 -58.4 13.4
    {0x25, 13},  // 25 -11.1 -54.3 -55.5 -60.1 -58.8 -59.1 -58.8 -58.4 -58.4 13.0
    {0x33, 11},  // 33 -12.2 -55.0 -56.3 -60.0 -58.7 -59.0 -58.9 -58.4 -58.4 12.8
    {0x1F, 11},  // 1F -13.3 -55.6 -57.2 -60.0 -58.8 -58.9 -58.9 -58.3 -58.4 12.4
    {0x1D, 12},  // 1D -14.5 -56.0 -58.0 -60.0 -58.8 -59.1 -58.7 -58.4 -58.5 12.1
    {0x32, 11},  // 32 -15.6 -56.9 -58.8 -59.9 -58.8 -59.0 -58.8 -58.3 -58.5 12.2
    {0x1A, 10},  // 1A -16.6 -57.3 -59.5 -59.9 -58.8 -59.1 -58.8 -58.4 -58.4 11.8
    {0x18, 19},  // 18 -18.5 -57.8 -60.3 -60.0 -58.8 -59.0 -58.9 -58.2 -58.5 11.6
    {0x17, 11},  // 17 -19.6 -58.7 -60.9 -60.0 -58.7 -58.9 -58.9 -58.5 -58.4 11.4
    {0x0C, 11},  // C -20.7 -59.4 -61.1 -60.0 -58.8 -59.1 -58.9 -58.4 -58.3 11.3
    {0x0A, 15},  // A -22.2 -59.9 -61.9 -60.0 -58.9 -59.0 -58.9 -58.4 -58.5 11.2
    {0x08, 18},  // 8 -24.0 -60.5 -62.5 -60.0 -58.7 -59.1 -58.8 -58.3 -58.5 11.1
    {0x07, 11},  // 7 -25.1 -61.3 -62.9 -60.1 -58.8 -59.1 -58.8 -58.4 -58.4 11.0
    {0x06, 13},  // 6 -26.4 -61.6 -63.2 -60.1 -58.7 -59.0 -58.9 -58.5 -58.5 11.0
    {0x05, 13},  // 5 -27.7 -62.3 -63.4 -60.1 -58.7 -59.2 -58.8 -58.4 -58.5 10.9
    {0x04, 19},  // 4 -29.6 -62.7 -63.6 -59.9 -58.7 -59.0 -58.9 -58.4 -58.4 10.8
};

static const PowerTableItem PA_TABLE_433[] = {
    {0xC0, 21},  // C0 9.9 -43.4 -45.0 -53.9 -55.2 -55.8 -52.3 -55.6 29.1
    {0xC3, 11},  // C3 8.8 -49.3 -45.9 -55.9 -55.4 -57.2 -52.6 -57.5 26.9
    {0xC6, 10},  // C6 7.8 -56.2 -46.9 -56.9 -55.6 -58.2 -53.2 -57.9 25.2
    {0xC9, 10},  // C9 6.8 -56.1 -47.9 -57.3 -55.9 -58.5 -54.0 -56.9 23.8
    {0xCC, 10},  // CC 5.8 -52.8 -48.9 -57.0 -56.1 -58.4 -54.6 -56.2 22.6
    {0x85, 10},  // 85 4.8 -54.2 -53.0 -58.3 -55.0 -57.8 -56.8 -58.0 19.1
    {0x88, 12},  // 88 3.6 -56.2 -53.8 -58.3 -55.7 -58.1 -57.2 -58.2 18.2
    {0x8B, 13},  // 8B 2.3 -57.7 -54.5 -58.0 -56.3 -58.1 -57.5 -58.2 17.3
    {0x8E, 19},  // 8E 0.4 -58.0 -55.5 -57.8 -57.4 -58.2 -58.1 -58.4 16.2
    {0x40, 12},  // 40 -0.8 -59.7 -56.1 -58.2 -57.7 -58.4 -58.3 -58.2 15.4
    {0x3C, 13},  // 3C -2.1 -60.6 -57.3 -58.2 -58.0 -58.5 -58.4 -58.5 19.3
    {0x3A, 10},  // 3A -3.1 -59.5 -57.5 -58.3 -58.3 -58.6 -58.1 -58.6 18.1
    {0x8F, 15},  // 8F -4.6 -52.2 -57.7 -58.1 -58.8 -58.4 -58.7 -58.3 14.4
    {0x37, 10},  // 37 -5.6 -56.8 -58.3 -58.3 -58.8 -58.4 -58.5 -58.4 16.2
    {0x36, 12},  // 36 -6.8 -56.8 -58.9 -58.3 -58.8 -58.3 -58.5 -58.5 15.6
    {0x28, 10},  // 28 -7.8 -56.6 -59.0 -58.2 -59.0 -58.4 -58.5 -58.4 15.1
    {0x26, 21},  // 26 -9.9 -57.0 -59.4 -58.3 -59.0 -58.4 -58.7 -58.4 14.3
    {0x25, 15},  // 25 -11.4 -57.3 -59.7 -58.4 -59.0 -58.3 -58.7 -58.5 13.9
    {0x24, 19},  // 24 -13.3 -57.9 -59.9 -58.2 -59.0 -58.6 -58.7 -58.5 13.5
    {0x1E, 10},  // 1E -14.3 -58.4 -59.8 -58.2 -59.0 -58.4 -58.6 -58.6 13.2
    {0x1C, 12},  // 1C -15.5 -58.6 -59.9 -58.4 -58.8 -58.6 -58.8 -58.5 12.9
    {0x1A, 15},  // 1A -17.0 -59.4 -59.9 -58.3 -59.1 -58.5 -58.7 -58.4 12.7
    {0x18, 18},  // 18 -18.8 -60.2 -59.9 -58.2 -59.0 -58.5 -58.7 -58.6 12.5
    {0x17, 10},  // 17 -19.8 -60.6 -59.9 -58.2 -58.9 -58.4 -58.7 -58.4 12.4
    {0x0C, 12},  // C -21.0 -61.1 -59.9 -58.4 -59.0 -58.5 -58.7 -58.6 12.3
    {0x15, 15},  // 15 -22.5 -61.7 -60.0 -58.2 -59.1 -58.3 -58.6 -58.7 12.2
    {0x08, 18},  // 8 -24.3 -62.3 -59.9 -58.3 -59.0 -58.4 -58.8 -58.5 12.1
    {0x07, 10},  // 7 -25.3 -62.6 -59.9 -58.2 -59.0 -58.6 -58.7 -58.5 12.0
    {0x06, 12},  // 6 -26.5 -63.2 -59.9 -58.3 -58.9 -58.5 -58.6 -58.6 12.0
    {0x05, 14},  // 5 -27.9 -63.5 -59.8 -58.3 -59.1 -58.5 -58.7 -58.4 11.9
    {0x04, 16},  // 4 -29.5 -63.7 -59.9 -58.3 -58.9 -58.5 -58.5 -58.5 11.9
};

static const PowerTableItem PA_TABLE_868[] = {
    {0xC0, 13},  // C0 10.7 -35.1 -58.6 -58.6 -57.5 -50.0 34.2
    {0xC3, 11},  // C3 9.6 -41.5 -58.5 -58.3 -57.4 -54.4 31.6
    {0xC6, 11},  // C6 8.5 -47.7 -58.5 -58.3 -57.6 -55.0 29.5
    {0xC9, 10},  // C9 7.5 -44.4 -58.5 -58.5 -57.7 -53.6 27.8
    {0xCC, 10},  // CC 6.5 -40.6 -58.6 -58.4 -57.6 -52.5 26.3
    {0xCE, 10},  // CE 5.5 -38.5 -58.5 -58.4 -57.8 -52.2 25.0
    {0x84, 11},  // 84 4.4 -35.3 -58.7 -58.5 -57.8 -55.8 20.3
    {0x87, 10},  // 87 3.4 -39.4 -58.6 -58.6 -57.8 -55.7 19.5
    {0xCF, 10},  // CF 2.4 -36.6 -58.6 -58.4 -57.7 -53.6 22.0
    {0x8C, 13},  // 8C 1.1 -50.2 -58.6 -58.5 -57.7 -55.9 17.9
    {0x50, 14},  // 50 -0.3 -42.1 -58.5 -58.5 -57.6 -57.1 16.9
    {0x40, 12},  // 40 -1.5 -43.2 -58.5 -58.7 -57.7 -57.2 16.1
    {0x3F, 11},  // 3F -2.6 -53.7 -58.6 -58.5 -57.8 -57.5 21.4
    {0x55, 10},  // 55 -3.6 -44.9 -58.6 -58.4 -57.8 -57.5 15.0
    {0x57, 12},  // 57 -4.8 -46.0 -58.6 -58.5 -57.6 -57.4 14.5
    {0x8F, 12},  // 8F -6.0 -51.6 -58.5 -58.6 -57.7 -57.1 15.0
    {0x2A, 14},  // 2A -7.4 -49.3 -58.5 -58.6 -57.7 -57.4 16.2
    {0x28, 16},  // 28 -9.0 -49.0 -58.5 -58.6 -57.7 -57.4 15.4
    {0x26, 20},  // 26 -11.0 -49.2 -58.5 -58.5 -57.7 -57.4 14.6
    {0x25, 15},  // 25 -12.5 -49.5 -58.6 -58.6 -57.8 -57.3 14.1
    {0x24, 18},  // 24 -14.3 -50.2 -58.5 -58.4 -57.8 -57.4 13.7
    {0x1D, 14},  // 1D -15.7 -50.7 -58.6 -58.6 -57.8 -57.5 13.3
    {0x1B, 13},  // 1B -17.0 -51.3 -58.5 -58.4 -57.7 -57.5 13.1
    {0x19, 16},  // 19 -18.6 -52.0 -58.6 -58.5 -57.8 -57.5 12.9
    {0x22, 10},  // 22 -19.6 -52.5 -58.5 -58.6 -57.7 -57.4 12.9
    {0x0D, 15},  // D -21.1 -53.3 -58.6 -58.6 -57.8 -57.4 12.6
    {0x0B, 12},  // B -22.3 -53.9 -58.6 -58.5 -57.8 -57.4 12.5
    {0x09, 15},  // 9 -23.8 -54.7 -58.5 -58.5 -57.8 -57.5 12.4
    {0x21, 10},  // 21 -24.8 -55.1 -58.5 -58.5 -57.7 -57.5 12.5
    {0x13, 17},  // 13 -26.5 -55.9 -58.6 -58.5 -57.6 -57.6 12.3
    {0x05, 12},  // 5 -27.7 -56.4 -58.4 -58.4 -57.7 -57.5 12.2
    {0x12, 12},  // 12 -28.9 -57.1 -58.4 -58.5 -57.7 -57.3 12.2
};

static const PowerTableItem PA_TABLE_915[] = {
    {0xC0, 26},  // C0 9.4 -33.5 -58.5 -58.4 -55.8 -32.6 31.8
    {0xC3, 11},  // C3 8.3 -41.5 -58.6 -58.4 -56.3 -38.0 29.3
    {0xC6, 11},  // C6 7.2 -42.5 -58.5 -58.4 -56.7 -40.5 27.4
    {0xC9, 10},  // C9 6.2 -37.6 -58.6 -58.4 -57.2 -38.8 25.9
    {0xCD, 12},  // CD 5.0 -34.2 -58.6 -58.5 -57.5 -37.3 24.3
    {0x84, 11},  // 84 3.9 -32.0 -58.6 -58.4 -57.7 -40.1 19.7
    {0x87, 10},  // 87 2.9 -36.5 -58.4 -58.5 -57.7 -39.6 18.9
    {0x8A, 11},  // 8A 1.8 -42.2 -58.5 -58.4 -57.7 -39.6 18.1
    {0x8D, 13},  // 8D 0.5 -46.8 -58.5 -58.5 -57.7 -40.4 17.3
    {0x8E, 11},  // 8E -0.6 -46.6 -58.5 -58.5 -57.8 -41.1 16.7
    {0x51, 10},  // 51 -1.6 -38.7 -58.4 -58.5 -57.7 -46.9 16.0
    {0x3E, 11},  // 3E -2.7 -50.0 -58.5 -58.4 -57.6 -55.3 20.7
    {0x3B, 11},  // 3B -3.8 -50.7 -58.6 -58.4 -57.6 -55.2 18.9
    {0x39, 13},  // 39 -5.1 -50.0 -58.5 -58.5 -57.6 -54.0 17.7
    {0x2B, 13},  // 2B -6.4 -47.6 -58.4 -58.4 -57.8 -52.1 16.5
    {0x36, 15},  // 36 -7.9 -46.9 -58.5 -58.4 -57.7 -51.2 15.8
    {0x35, 14},  // 35 -9.3 -46.7 -58.6 -58.4 -57.7 -50.7 15.2
    {0x26, 16},  // 26 -10.9 -47.0 -58.6 -58.4 -57.8 -50.9 14.5
    {0x25, 14},  // 25 -12.3 -47.2 -58.6 -58.3 -57.7 -51.0 14.1
    {0x24, 18},  // 24 -14.1 -48.1 -58.4 -58.4 -57.8 -51.4 13.7
    {0x1D, 14},  // 1D -15.5 -48.7 -58.4 -58.5 -57.7 -51.9 13.2
    {0x1B, 13},  // 1B -16.8 -49.3 -58.6 -58.4 -57.8 -52.3 13.0
    {0x19, 15},  // 19 -18.3 -50.2 -58.5 -58.5 -57.6 -52.8 12.8
    {0x18, 10},  // 18 -19.3 -50.6 -58.5 -58.5 -57.7 -53.1 12.7
    {0x17, 10},  // 17 -20.3 -51.2 -58.6 -58.5 -57.8 -53.1 12.6
    {0x0C, 11},  // C -21.4 -51.8 -58.4 -58.5 -57.7 -53.4 12.5
    {0x0A, 13},  // A -22.7 -52.6 -58.5 -58.4 -57.7 -53.6 12.4
    {0x08, 16},  // 8 -24.3 -53.6 -58.4 -58.4 -57.6 -54.1 12.3
    {0x13, 19},  // 13 -26.2 -54.6 -58.4 -58.5 -57.7 -54.3 12.2
    {0x05, 11},  // 5 -27.3 -55.3 -58.4 -58.4 -57.8 -54.5 12.1
    {0x12, 13},  // 12 -28.6 -55.9 -58.6 -58.5 -57.7 -54.7 12.1
    {0x03, 12},  // 3 -29.8 -56.9 -58.5 -58.4 -57.7 -54.7 12.0
};
}  // namespace esphome::cc1101
